(() => {
  var currentHash; //最新的hash
  var lastHash; //上一次的hash
  function hotCheck(){
    console.log('开始进行热更新检查')
    hotDownloadManifest().then(update=>{
      update.c.forEach((chunkID)=>{
        hotDownloadUpdateChunk(chunkID);
      })
      lastHash = currentHash;
    
    }).catch((err)=>{
      window.location.reload()
    })
  };
  // 通过fetch下载最新的hot-update.json文件内容
  function hotDownloadManifest(){
    // webpack4=>ajax  webpack5=>fetch
    return fetch(`main.${lastHash}.hot-update.json`).then(res=>res.json())
  }
  function hotDownloadUpdateChunk(chunkID){
    let script = document.createElement("script");
    script.src = `${chunkID}.${lastHash}.hot-update.js`;
    document.head.appendChild(script);
  }
  self['webpackHotUpdate'] = function(chunkId,moreModules){
    hotAddUpdateChunk(chunkId, moreModules);
  }
  /**
   * 
   * @param {*} chunkId 
   * @param {*} moreModules 新的模块代码
   */
   let hotUpdate = {};
  function hotAddUpdateChunk(chunkId, moreModules){
    for (const moduleId in moreModules) {
      // 合并到模块定义对象内，
      hotUpdate[moduleId] = modules[moduleId] = moreModules[moduleId];
    }
    hotApply();
  }
  function hotApply(){
    for (const moduleId in hotUpdate) {
      let oldModule = cache[moduleId]//获取到老的模块 
      delete cache[moduleId] //把老的缓存删除，不然再加载还会读到老的模块
      if(oldModule.parents && oldModule.parents.length >0){
        oldModule.parents.forEach((parentModule) => {
          parentModule.hot._acceptedDependencies[moduleId]&&parentModule.hot._acceptedDependencies[moduleId]();
        })
      }
    }
  }

  var modules = ({
    "./src/index.js":((module,exports,require)=>{
      let render = () => {
        let title = require("./src/title.js");
        root.innerText = title;
      }
      render();
      if (true) {
        // 当title.js模块发生修改的时候，执行render方法这个回调函数
        module.hot.accept([/*! ./title.js */ "./src/title.js"], render);
      }
    }),
    "./src/title.js": ((module) => {
      module.exports = 'title4';
    }),
    "./webpack/hot/emitter.js": ((module) => {
      class EventEmitter {
        constructor() {
          this.events = {};
        }
        on(eventName, fn) {
          this.events[eventName] = fn;
        }
        emit(eventName, ...args) {
          this.events[eventName](...args);
        }
      }
      module.exports = new EventEmitter();
    })
  });
  var cache = {};

  


  function hotCreateModule() {
    var hot = {
      _acceptedDependencies: {},//接收的依赖
      accept:function(deps,callback){//接收依赖的变化,注册各个模块的回调函数
        for (var i = 0; i < deps.length; i++){
          hot._acceptedDependencies[deps[i]] = callback;
        }
      },
      check: hotCheck,
    }
    return hot
  };

  /**
   * 
   * @param {*} parentModuleId 父模块id
   * @returns 
   */
  function hotCreateRequire(parentModuleId) {
    //先判断父模块是否加载过，如果没有加载过，就返回require
    var parentModule = cache[parentModuleId]; 
    if(!parentModule)return require
    var hotRequire = function(childModuleId){
      parentModule.children.push(childModuleId) //给父亲添加一个儿子
      require(childModuleId);
      let childModule = cache[childModuleId];
      childModule.parents.push(parentModule);
      return childModule.exports;
    }
    return hotRequire
  }

  function require(moduleId) {
    var cachedModule = cache[moduleId];
    if (cachedModule !== undefined) {
      return cachedModule.exports;
    }
    var module = cache[moduleId] = {
      exports: {},
      hot:hotCreateModule(),//每个模块都会多一个hot属性，用来注册热更新回调
      parents:[],//父模块数组
      children:[],//子模块数组
    };
    modules[moduleId](module, module.exports, hotCreateRequire(moduleId));
    return module.exports;
  }
  var exports = {};
  (() => {
    var hotEmitter = require("./webpack/hot/emitter.js");
    var socket = io();
    socket.on("hash", (hash) => {
      console.log('客户端拿到hash消息')
      currentHash = hash;
    });
    socket.on("ok", () => {
      console.log('客户端拿到ok消息')
      reloadApp();
    });

    function reloadApp() {
      hotEmitter.emit("webpackHotUpdate", currentHash);
    }
  })();
  (() => {
    var hotEmitter = require("./webpack/hot/emitter.js");
    hotEmitter.on("webpackHotUpdate", (currentHash) => {
      if(!lastHash){
        lastHash = currentHash
        console.log('这是第一次收到hash，是首次渲染')
        return
      }
      console.log('lasthash',lastHash,'currenthash',currentHash,'开始真正热更新')
      hotCheck() //热更新检查
    })
  })();
  // debugger
  return hotCreateRequire('./src/index.js')('./src/index.js')
})();